<?php

namespace App\Http\Controllers;

use App\Exceptions\InvalidRequestException;
use App\Models\Category;
use App\Models\Product;
use App\Services\CategoryService;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;

class ProductsController extends Controller
{
    // public function index(Request $request,CategoryService $categoryService){
    public function index(Request $request){
        $page = $request->input("page",1);
        $perPage = 16;

        //构造查询
        $params = [
            "index" => "products",
            "body" => [
                "from" => ($page - 1) * $perPage,//通过当前页数和每页数量计算偏移量
                "size" => $perPage,
                "query" => [
                    "bool" => [
                        "filter" => [
                            ['term' => ['on_sale' => true]]
                        ]
                    ]
                ]
            ]
        ];
        
        // $builder = Product::query()->where("on_sale",true);
        // $order = "";
        // if($search = $request->input("search",'')){
        //     $like = "%".$search."%";
        //     //模糊搜索

        //     $builder->where(function ($query)use($like){
        //         $query->where("title","like",$like)
        //             ->orWhere('description', 'like', $like)
        //             ->orWhereHas("skus",function ($query)use($like){
        //                 $query->where('title', 'like', $like)
        //                     ->orWhere('description', 'like', $like);
        //             });
        //     });
        // }

        if($order = $request->input("order","")){
            if(preg_match("/^(.+)_(asc|desc)$/",$order,$m)){
                if(in_array($m[1],["price","sold_count","rating"])){
                    $params['body']['sort'] = [[$m[1] => $m[2]]];
                    // $builder->orderBy($m[1],$m[2]);
                }
            }
        }

        if ($request->input('category_id') && $category = Category::find($request->input('category_id'))) {
            if ($category->is_directory) {
                // 如果是一个父类目，则使用 category_path 来筛选
                $params['body']['query']['bool']['filter'][] = [
                    'prefix' => ['category_path' => $category->path.$category->id.'-'],
                ];
            } else {
                // 否则直接通过 category_id 筛选
                $params['body']['query']['bool']['filter'][] = ['term' => ['category_id' => $category->id]];
            }
        }

        if ($search = $request->input('search', '')) {
            // 将搜索词根据空格拆分成数组，并过滤掉空项
            $keywords = array_filter(explode(' ', $search));

            $params['body']['query']['bool']['must'] = [];
            // 遍历搜索词数组，分别添加到 must 查询中
            foreach ($keywords as $keyword) {
                $params['body']['query']['bool']['must'][] = [
                    'multi_match' => [
                        'query'  => $keyword,
                        'fields' => [
                            'title^2',
                            'long_title^2',
                            'category^2',
                            'description',
                            'skus_title',
                            'skus_description',
                            'properties_value',
                        ],
                    ],
                ];
            }
        }
        $result = app("es")->search($params);
       
        
        //通过collect函数返回结果转为集合，并通过集合的pluck方法取到返回商品的id数值
        $productIds = collect($result['hits']['hits'])->pluck('_id')->all();

        //通过 whereIn 方法从数据库中读取商品数据
        $products = Product::query()->whereIn("id",$productIds)
                    ->orderByRaw(sprintf("FIND_IN_SET(id,'%s')",join(',',$productIds)))->get();

        //返回一个lengthAwarePaginator对象
        $pager = new LengthAwarePaginator($products,$result["hits"]['total']["value"],
                    $perPage,$page,[
                        "path" => route("products.index",false),//手动构建分页的url
                    ]);
        return view('products.index', [
            'products' => $pager,
            'filters'  => [
                'search' => $search,
                'order'  => $order,
            ],
            'category' => $category ?? null,
        ]);
        // // 如果有传入 category_id 字段，并且在数据库中有对应的类目
        // if ($request->input('category_id') && $category = Category::find($request->input('category_id'))) {
        //     // 如果这是一个父类目
        //     if ($category->is_directory) {
        //         // 则筛选出该父类目下所有子类目的商品
        //         $builder->whereHas('category', function ($query) use ($category) {
        //             // 这里的逻辑参考本章第一节
        //             $query->where('path', 'like', $category->path.$category->id.'-%');
        //         });
        //     } else {
        //         // 如果这不是一个父类目，则直接筛选此类目下的商品
        //         $builder->where('category_id', $category->id);
        //     }
        // }
        // $products = $builder->paginate(16);

        // return view("products.index",[
        //     'products'=>$products,
        //     "filters" => [
        //         "search" => $search,
        //         "order" => $order,
        //     ],
        //     // 等价于 isset($category) ? $category : null
        //     'category' => $category ?? null,
        //       // 将类目树传递给模板文件
        //       'categoryTree' => $categoryService->getCategoryTree(),
        // ]);
    }

    public function show(Product $product,Request $request){
        if(!$product->on_sale){
            throw  new InvalidRequestException("商品未上架");
        }
        $favored = false;

        //用户未登录时候返回null，已登陆时候返回的是对应的用户对象
        if($user = $request->user()){
            //从当前用户已收藏的id搜索当前商品的ID
            $favored = boolval($user->favoriteProducts()->find($product->id));
        }
        return view("products.show",['product' => $product,"favored" =>$favored]);
    }

    public function favor(Product $product,Request $request){
        $user = $request->user();
        if($user->favoriteProducts()->find($product->id)){
            return [];
        }

        //attach()方法可以将用户和商品关联起来，可以放入模型对象本身
        //也可以放入商品ID
        $user->favoriteProducts()->attach($product);
        return [];
    }

    public function disfavor(Product $product,Request $request){
        $user = $request->user();
        //detach()方法取消多对多的关联
        $user->favoriteProducts()->detach($product);
        return [];
    }

    public function favorites(Request $request){
        $products = $request->user()->favoriteProducts()->paginate(16);
        return view("products.favorites",['products'=>$products]);
    }
}
